<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.1">
  <link rel="apple-touch-icon" sizes="180x180" href="/blog/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/blog/images/favicon-32x32.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/blog/images/favicon-16x16.png">
  <link rel="mask-icon" href="/blog/images/logo.svg" color="#222">

<link rel="stylesheet" href="/blog/css/main.css">


<link rel="stylesheet" href="/blog/lib/font-awesome/css/all.min.css">
  <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/@fancyapps/fancybox@3/dist/jquery.fancybox.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"gitee.com","root":"/blog/","scheme":"Muse","version":"8.0.0-rc.4","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":true,"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
  </script>

  <meta name="description" content="面向对象Q&amp;A1. 问: 为什么类的私有属性(例如:__name),从外部不能直接访问?答: 因为实例化以后会改变私有属性的名称, 变成 “__类名__私有属性”, 所以不能用原来的私有属性直接访问;另外也并不建议使用”__类名__私有属性”去强行访问,因为不同版本的解释器有可能会把私有属性改成不同的属性名!">
<meta property="og:type" content="article">
<meta property="og:title" content="Python面向对象的问与答">
<meta property="og:url" content="https://gitee.com/indoorsman_lab/blog/2020/07/03/Python%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%9A%84%E9%97%AE%E4%B8%8E%E7%AD%94/index.html">
<meta property="og:site_name" content="宅人类研究室">
<meta property="og:description" content="面向对象Q&amp;A1. 问: 为什么类的私有属性(例如:__name),从外部不能直接访问?答: 因为实例化以后会改变私有属性的名称, 变成 “__类名__私有属性”, 所以不能用原来的私有属性直接访问;另外也并不建议使用”__类名__私有属性”去强行访问,因为不同版本的解释器有可能会把私有属性改成不同的属性名!">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2020-07-03T10:53:53.000Z">
<meta property="article:modified_time" content="2020-07-19T08:21:09.408Z">
<meta property="article:author" content="张雪峰">
<meta property="article:tag" content="面向对象">
<meta name="twitter:card" content="summary">

<link rel="canonical" href="https://gitee.com/indoorsman_lab/blog/2020/07/03/Python%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%9A%84%E9%97%AE%E4%B8%8E%E7%AD%94/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>Python面向对象的问与答 | 宅人类研究室</title>
  






  <noscript>
  <style>
  body { margin-top: 2rem; }

  .use-motion .header,
  .use-motion .site-brand-container .toggle,
  .use-motion .menu-item,
  .use-motion .sidebar,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header,
  .use-motion .footer { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle,
  .use-motion .custom-logo-image {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line {
    transform: scaleX(1);
  }

  .search-pop-overlay, .sidebar-nav { display: none; }
  .sidebar-panel { display: block; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <main class="main">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader">
        <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
        <span class="toggle-line toggle-line-first"></span>
        <span class="toggle-line toggle-line-middle"></span>
        <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/blog/" class="brand" rel="start">
      <i class="logo-line"></i>
      <h1 class="site-title">宅人类研究室</h1>
      <i class="logo-line"></i>
    </a>
      <p class="site-subtitle" itemprop="description">IndoorsMan Lab</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/blog/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a>

  </li>
        <li class="menu-item menu-item-about">

    <a href="/blog/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/blog/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/blog/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/blog/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a>

  </li>
  </ul>
</nav>




</div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <section class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#面向对象Q-amp-A"><span class="nav-number">1.</span> <span class="nav-text">面向对象Q&amp;A</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#1-问-为什么类的私有属性-例如-name-从外部不能直接访问"><span class="nav-number">1.0.0.1.</span> <span class="nav-text">1. 问: 为什么类的私有属性(例如:__name),从外部不能直接访问?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-因为实例化以后会改变私有属性的名称-变成-“-类名-私有属性”-所以不能用原来的私有属性直接访问-另外也并不建议使用”-类名-私有属性”去强行访问-因为不同版本的解释器有可能会把私有属性改成不同的属性名"><span class="nav-number">1.0.0.1.1.</span> <span class="nav-text">答: 因为实例化以后会改变私有属性的名称, 变成 “__类名__私有属性”, 所以不能用原来的私有属性直接访问;另外也并不建议使用”__类名__私有属性”去强行访问,因为不同版本的解释器有可能会把私有属性改成不同的属性名!</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#2-问-一个类中的单下划线属性-例如-age-是私有属性吗"><span class="nav-number">1.0.0.2.</span> <span class="nav-text">2. 问: 一个类中的单下划线属性(例如: _age)是私有属性吗?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-其实单下划线开头的属性并不是私有属性-但是约定俗称的视为私有-所以即使可以从外部直接访问-但是不建议"><span class="nav-number">1.0.0.2.1.</span> <span class="nav-text">答: 其实单下划线开头的属性并不是私有属性,但是约定俗称的视为私有, 所以即使可以从外部直接访问,但是不建议</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-问-类里面前后都有双下划线的属性-例如-name-是啥-能直接访问吗"><span class="nav-number">1.0.0.3.</span> <span class="nav-text">3. 问: 类里面前后都有双下划线的属性(例如:__name__)是啥,能直接访问吗?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-是特殊属性-可以直接从外部访问-但是因为本身有特殊用途的属性才这样命名-所以一般我们定义的属性不能使用这种方式命名"><span class="nav-number">1.0.0.3.1.</span> <span class="nav-text">答: 是特殊属性, 可以直接从外部访问, 但是因为本身有特殊用途的属性才这样命名,所以一般我们定义的属性不能使用这种方式命名!</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-问-私有属性不能从外部访问-那如果就想访问怎么办呢"><span class="nav-number">1.0.0.4.</span> <span class="nav-text">4. 问: 私有属性不能从外部访问, 那如果就想访问怎么办呢?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-可以定义获取私有属性的方法-把私有属性给return出来"><span class="nav-number">1.0.0.4.1.</span> <span class="nav-text">答: 可以定义获取私有属性的方法, 把私有属性给return出来</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-问-不仅想从外部访问私有属性-还想修改私有属性-怎么办"><span class="nav-number">1.0.0.5.</span> <span class="nav-text">5. 问: 不仅想从外部访问私有属性, 还想修改私有属性,怎么办?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-还是可以定义一个修改私有属性的方法-通过调用方法去修改私有属性的值"><span class="nav-number">1.0.0.5.1.</span> <span class="nav-text">答: 还是可以定义一个修改私有属性的方法,通过调用方法去修改私有属性的值</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#6-问-如果从外部动态的修改私有属性-能修改成功吗"><span class="nav-number">1.0.0.6.</span> <span class="nav-text">6. 问 : 如果从外部动态的修改私有属性,能修改成功吗?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-首先从外部动态绑定的属性-即使前缀是双下划线-甚至和原来的私有属性同名-它都不会是一个私有属性-而是一个新的普通实例属性-可以从外部直接访问-而且私有属性在实例化以后其实已经不再是原来的名字了-新的名字不容易推断-会根据解释器不同而改变-所以仅和类中定义的私有属性同名是无法修改私有属性的"><span class="nav-number">1.0.0.6.1.</span> <span class="nav-text">答: 首先从外部动态绑定的属性, 即使前缀是双下划线, 甚至和原来的私有属性同名, 它都不会是一个私有属性, 而是一个新的普通实例属性, 可以从外部直接访问;而且私有属性在实例化以后其实已经不再是原来的名字了(新的名字不容易推断,会根据解释器不同而改变), 所以仅和类中定义的私有属性同名是无法修改私有属性的</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#7-问-私有属性干什么用的"><span class="nav-number">1.0.0.7.</span> <span class="nav-text">7. 问: 私有属性干什么用的?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-限制访问用的-当你不想让外部代码随意改变对象的内部状态时-就可以使用私有属性-私有变量-把内部变量保护起来"><span class="nav-number">1.0.0.7.1.</span> <span class="nav-text">答: 限制访问用的, 当你不想让外部代码随意改变对象的内部状态时, 就可以使用私有属性(私有变量)把内部变量保护起来</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#8-问-啥是基类-啥是父类-啥又是超类"><span class="nav-number">1.0.0.8.</span> <span class="nav-text">8. 问: 啥是基类?啥是父类?啥又是超类?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-基类-父类-超类-本身就是同一个概念-都是指面向对象继承中被继承的一方"><span class="nav-number">1.0.0.8.1.</span> <span class="nav-text">答: 基类 父类 超类 本身就是同一个概念, 都是指面向对象继承中被继承的一方!</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#9-问-多态是啥东西"><span class="nav-number">1.0.0.9.</span> <span class="nav-text">9: 问: 多态是啥东西?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-我们在定义类class时-其实就是定义了一个数据类型-那么实例后的对象自然就属于这个类型-又因为有继承的存在-那么实例对象既是当前类的数据类型-又是父类的数据类型-反之则不行"><span class="nav-number">1.0.0.9.1.</span> <span class="nav-text">答: 我们在定义类class时, 其实就是定义了一个数据类型, 那么实例后的对象自然就属于这个类型; 又因为有继承的存在, 那么实例对象既是当前类的数据类型,又是父类的数据类型, 反之则不行!</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#10-问-多态有啥好处"><span class="nav-number">1.0.0.10.</span> <span class="nav-text">10. 问: 多态有啥好处?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-继承自统一个父类的所有子类-如果都有一个同名方法-那么如果公共方法正好调用对象的这个同名方法时-在传入不同实例的情况下会自动调用对应的方法-而不用修改公共方法本身"><span class="nav-number">1.0.0.10.1.</span> <span class="nav-text">答: 继承自统一个父类的所有子类, 如果都有一个同名方法, 那么如果公共方法正好调用对象的这个同名方法时, 在传入不同实例的情况下会自动调用对应的方法, 而不用修改公共方法本身!</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#11-问-啥是鸭子类型"><span class="nav-number">1.0.0.11.</span> <span class="nav-text">11. 问: 啥是鸭子类型?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-对于静态语言（例如Java）来说，如果需要传入Animal类型，则传入的对象必须是Animal类型或者它的子类，否则，将无法调用run-方法。对于Python这样的动态语言来说，则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run-方法就可以了-这就是动态语言的“鸭子类型”，它并不要求严格的继承体系"><span class="nav-number">1.0.0.11.1.</span> <span class="nav-text">答:  对于静态语言（例如Java）来说，如果需要传入Animal类型，则传入的对象必须是Animal类型或者它的子类，否则，将无法调用run()方法。对于Python这样的动态语言来说，则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了;这就是动态语言的“鸭子类型”，它并不要求严格的继承体系</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#12-问-可以给类动态地绑定方法吗"><span class="nav-number">1.0.0.12.</span> <span class="nav-text">12. 问: 可以给类动态地绑定方法吗?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-可以-直接在外部使用-“类名-方法名-方法”即可"><span class="nav-number">1.0.0.12.1.</span> <span class="nav-text">答: 可以, 直接在外部使用 “类名.方法名 &#x3D; 方法”即可</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#13-问-想要限制从外部添加的实例属性-怎么做"><span class="nav-number">1.0.0.13.</span> <span class="nav-text">13. 问: 想要限制从外部添加的实例属性, 怎么做?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-在类的内部-使用特殊变量-slots-“-“-“-“-…-去限定能够添加的属性名-试图从外部添加限定外的属性时-会报错"><span class="nav-number">1.0.0.13.1.</span> <span class="nav-text">答:在类的内部, 使用特殊变量__slots__&#x3D;(“ “, “  “, …)去限定能够添加的属性名, 试图从外部添加限定外的属性时, 会报错</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#14-问-slots-定义的限制属性对子类实例起作用吗"><span class="nav-number">1.0.0.14.</span> <span class="nav-text">14. 问: __slots__定义的限制属性对子类实例起作用吗?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-slots-定义的属性仅对当前类实例起作用，对继承的子类是不起作用的"><span class="nav-number">1.0.0.14.1.</span> <span class="nav-text">答: __slots__定义的属性仅对当前类实例起作用，对继承的子类是不起作用的;</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#15-问-如果父类定义了-slots-子类中又定义了-slots-会怎么样"><span class="nav-number">1.0.0.15.</span> <span class="nav-text">15. 问: 如果父类定义了 __slots__, 子类中又定义了 __slots__会怎么样?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-此时-子类实例限制添加的属性就等于”父类限制-子类限制”-也就是如果子类也定义-slots-则自动继承父类的-slots"><span class="nav-number">1.0.0.15.1.</span> <span class="nav-text">答: 此时, 子类实例限制添加的属性就等于”父类限制+子类限制”, 也就是如果子类也定义 __slots__则自动继承父类的 __slots__</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#16-问-为什么需要-property装饰器呢"><span class="nav-number">1.0.0.16.</span> <span class="nav-text">16. 问: 为什么需要@property装饰器呢?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-直接使用外部添加、修改、访问的方式去操作属性-太暴露且不能定义参数检验-容易导致属性被胡乱修改-而在类的内部对一个属性定义多个操作函数又略显杂乱-所以此时就需要-property装饰器把函数当属性用"><span class="nav-number">1.0.0.16.1.</span> <span class="nav-text">答: 直接使用外部添加、修改、访问的方式去操作属性, 太暴露且不能定义参数检验, 容易导致属性被胡乱修改; 而在类的内部对一个属性定义多个操作函数又略显杂乱, 所以此时就需要@property装饰器把函数当属性用</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#17-问-property装饰器的好处是啥"><span class="nav-number">1.0.0.17.</span> <span class="nav-text">17. 问 : @property装饰器的好处是啥?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-可以让调用者写出简短的代码，同时保证对参数进行必要的检查，这样，程序运行时就减少了出错的可能性"><span class="nav-number">1.0.0.17.1.</span> <span class="nav-text">答: 可以让调用者写出简短的代码，同时保证对参数进行必要的检查，这样，程序运行时就减少了出错的可能性</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#18-问-怎么使用-property装饰器呢"><span class="nav-number">1.0.0.18.</span> <span class="nav-text">18. 问: 怎么使用@property装饰器呢?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-首先在获取属性的方法加上-property装饰器-然后在设置-修改-属性的方法上面加上-属性名-setter的装饰器-如果是只读属性就在读方法上面加一个-property装饰器即可"><span class="nav-number">1.0.0.18.1.</span> <span class="nav-text">答: 首先在获取属性的方法加上@property装饰器, 然后在设置(修改)属性的方法上面加上@属性名.setter的装饰器, 如果是只读属性就在读方法上面加一个@property装饰器即可</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#19-问-怎么理解Mixin"><span class="nav-number">1.0.0.19.</span> <span class="nav-text">19. 问: 怎么理解Mixin?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-多继承中-非主线继承的类-为了增加混入的其他功能的类在命名时一般会加上Mixin以作区别-通过直接继承Mixin类-可以避免设计过于复杂的继承路线-使类的层级结构更清晰"><span class="nav-number">1.0.0.19.1.</span> <span class="nav-text">答: 多继承中,非主线继承的类, 为了增加混入的其他功能的类在命名时一般会加上Mixin以作区别;通过直接继承Mixin类,可以避免设计过于复杂的继承路线, 使类的层级结构更清晰</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#20-问-str-和-repr-分别是干嘛用的"><span class="nav-number">1.0.0.20.</span> <span class="nav-text">20. 问: __str__和__repr__分别是干嘛用的?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-都是可以自定义输出格式的方法-str-主要面向用户-而-repr-主要是给程序员看的-使用print-方法打印对象-才会调用-str-如果直接显示变量-例如在控制台-则会调用-repr-偷懒的定义方法-只定义一个-str-然后-repr-str-即可统一输出格式"><span class="nav-number">1.0.0.20.1.</span> <span class="nav-text">答: 都是可以自定义输出格式的方法; __str__主要面向用户, 而 __repr__主要是给程序员看的, 使用print()方法打印对象, 才会调用 __str__, 如果直接显示变量(例如在控制台)则会调用 __repr__; 偷懒的定义方法, 只定义一个__str__,然后 __repr__ &#x3D; __str__即可统一输出格式</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#21-问-iter-干嘛用的-next-又是干嘛用的"><span class="nav-number">1.0.0.21.</span> <span class="nav-text">21. 问: __iter__()干嘛用的?__next__()又是干嘛用的?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-如果一个类想要用于for-in-循环-则必须实现一个-iter-方法-返回一个可迭代对象-也就是实例本身self-for循环就会不断地调用实例的-next-方法拿到循环的下一个值-直到StopIteration"><span class="nav-number">1.0.0.21.1.</span> <span class="nav-text">答: 如果一个类想要用于for in 循环, 则必须实现一个__iter__()方法, 返回一个可迭代对象, 也就是实例本身self ; for循环就会不断地调用实例的__next__()方法拿到循环的下一个值, 直到StopIteration</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#22-问-一个可迭代的实例对象-想要使用下标和切片访问-怎么实现"><span class="nav-number">1.0.0.22.</span> <span class="nav-text">22. 问: 一个可迭代的实例对象, 想要使用下标和切片访问, 怎么实现?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-使用-getitem-方法实现-注意需要判断传入的参数是int还是slice类型-以区别下标访问和切片访问-但是这里的切片不能对step参数处理-也就是不能自定义步长-同时也不能使用复数"><span class="nav-number">1.0.0.22.1.</span> <span class="nav-text">答: 使用__getitem__()方法实现, 注意需要判断传入的参数是int还是slice类型, 以区别下标访问和切片访问; 但是这里的切片不能对step参数处理, 也就是不能自定义步长, 同时也不能使用复数</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#23-问-除了-getitem-以外-setitem-和-delitem-又是干嘛用的"><span class="nav-number">1.0.0.23.</span> <span class="nav-text">23. 问: 除了__getitem__()以外, __setitem__()和__delitem__()又是干嘛用的?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-setitem-把实例对象视为list或dict来对集合赋值-delitem-用来删除某个元素-通过这3个方法-我们自己构造的类和python自带的list-tuple-dict-也差不多了-类似鸭子类型"><span class="nav-number">1.0.0.23.1.</span> <span class="nav-text">答:  __setitem__()把实例对象视为list或dict来对集合赋值, __delitem__()用来删除某个元素; 通过这3个方法, 我们自己构造的类和python自带的list, tuple, dict 也差不多了, 类似鸭子类型</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#24-问-getattr-self-attr-是用来做什么的"><span class="nav-number">1.0.0.24.</span> <span class="nav-text">24. 问: __getattr__(self, attr)是用来做什么的?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-访问类中不存在的属性或者调用不存在的方法时-会调用-getattr-方法-可以自定义返回的值-默认返回None值-可以使用-raise-AttributeError-“-“-attr-去格式化想输出的错误信息"><span class="nav-number">1.0.0.24.1.</span> <span class="nav-text">答: 访问类中不存在的属性或者调用不存在的方法时, 会调用 __getattr__方法, 可以自定义返回的值 ; 默认返回None值, 可以使用 raise AttributeError (“  “, attr)去格式化想输出的错误信息</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#25-问-当一个实例想要调用实例方法时-一般会以instance-method-这种方式调用-那可不可以直接使用instance-调用呢"><span class="nav-number">1.0.0.25.</span> <span class="nav-text">25. 问: 当一个实例想要调用实例方法时, 一般会以instance.method()这种方式调用, 那可不可以直接使用instance()调用呢?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-可以-定义一个-call-方法-相当于就把实例对象看成一个函数去调用"><span class="nav-number">1.0.0.25.1.</span> <span class="nav-text">答: 可以, 定义一个__call__()方法, 相当于就把实例对象看成一个函数去调用</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#26-问-那怎么判断一个对象能否被调用呢"><span class="nav-number">1.0.0.26.</span> <span class="nav-text">26. 问: 那怎么判断一个对象能否被调用呢?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-只需要判断一个对象是否可以被调用-使用callable-对象-函数判断是否是可调用callable的对象"><span class="nav-number">1.0.0.26.1.</span> <span class="nav-text">答: 只需要判断一个对象是否可以被调用, 使用callable(对象)函数判断是否是可调用callable的对象,</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#27-问-需要定义常量时-怎么使用枚举类"><span class="nav-number">1.0.0.27.</span> <span class="nav-text">27. 问: 需要定义常量时, 怎么使用枚举类?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-from-enum-import-Enum-导入枚举类-枚举类的value属性是自动赋值给成员的int型常量-注意是从1开始的-还可以导入-unique装饰器保证没有重复值"><span class="nav-number">1.0.0.27.1.</span> <span class="nav-text">答: from enum import Enum 导入枚举类, 枚举类的value属性是自动赋值给成员的int型常量, 注意是从1开始的   ; 还可以导入@unique装饰器保证没有重复值</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#28-问-不使用class还能怎么样创建一个类呢"><span class="nav-number">1.0.0.28.</span> <span class="nav-text">28. 问: 不使用class还能怎么样创建一个类呢?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-使用type-既可以查看对象的类型-同时又可用于创建类-事实上解释器在扫描完class定义的语法后就是使用type去创建这个类的-使用type-相当于是动态的创建类-type-类名-继承的父类-…-dict-类的方法名-外部方法"><span class="nav-number">1.0.0.28.1.</span> <span class="nav-text">答: 使用type()既可以查看对象的类型, 同时又可用于创建类 ; 事实上解释器在扫描完class定义的语法后就是使用type去创建这个类的; 使用type()相当于是动态的创建类, type(类名, (继承的父类, …), dict(类的方法名&#x3D;外部方法))</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#29-问-什么是元类metaclass"><span class="nav-number">1.0.0.29.</span> <span class="nav-text">29. 问: 什么是元类metaclass?</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#答-元类允许创建或修改类-metaclass-gt-class-gt-instance-元类用来控制类的创建行为-定义元类一般以Metaclass结尾-是Python面向对象里最难理解，也是最难使用的魔术代码"><span class="nav-number">1.0.0.29.1.</span> <span class="nav-text">答:  元类允许创建或修改类 metaclass&#x3D;&#x3D;&gt;class&#x3D;&#x3D;&gt;instance, 元类用来控制类的创建行为, 定义元类一般以Metaclass结尾, 是Python面向对象里最难理解，也是最难使用的魔术代码</span></a></li></ol></li></ol></li></ol></li></ol></li></ol></div>
      </section>
      <!--/noindex-->

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="张雪峰"
      src="/blog/images/avatar.jpg">
  <p class="site-author-name" itemprop="name">张雪峰</p>
  <div class="site-description" itemprop="description">IndoorsMan Lab</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/blog/archives/">
        
          <span class="site-state-item-count">15</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/blog/categories/">
          
        <span class="site-state-item-count">5</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/blog/tags/">
          
        <span class="site-state-item-count">12</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://github.com/indoorsmanlab" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;indoorsmanlab" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
      <span class="links-of-author-item">
        <a href="https://gitee.com/indoorsman_lab" title="Gitee → https:&#x2F;&#x2F;gitee.com&#x2F;indoorsman_lab"><i class="fab fa-git-square fa-fw"></i>Gitee</a>
      </span>
  </div>


  <div class="links-of-blogroll motion-element">
    <div class="links-of-blogroll-title"><i class="fa fa-globe fa-fw"></i>
      Links
    </div>
    <ul class="links-of-blogroll-list">
        <li class="links-of-blogroll-item">
          <a href="https://blog.csdn.net/m0_46238775" title="https:&#x2F;&#x2F;blog.csdn.net&#x2F;m0_46238775" rel="noopener" target="_blank">宅人类研究室-CSDN</a>
        </li>
    </ul>
  </div>

      </section>
    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </header>

      
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>

  <a href="https://github.com/indoorsmanlab" class="github-corner" title="Follow me on GitHub" aria-label="Follow me on GitHub" rel="noopener" target="_blank"><svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a>

<noscript>
  <div id="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


      <div class="main-inner">
        

        <div class="content post posts-expand">
          

    
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://gitee.com/indoorsman_lab/blog/2020/07/03/Python%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%9A%84%E9%97%AE%E4%B8%8E%E7%AD%94/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/blog/images/avatar.jpg">
      <meta itemprop="name" content="张雪峰">
      <meta itemprop="description" content="IndoorsMan Lab">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="宅人类研究室">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          Python面向对象的问与答
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2020-07-03 18:53:53" itemprop="dateCreated datePublished" datetime="2020-07-03T18:53:53+08:00">2020-07-03</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2020-07-19 16:21:09" itemprop="dateModified" datetime="2020-07-19T16:21:09+08:00">2020-07-19</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/blog/categories/Python/" itemprop="url" rel="index"><span itemprop="name">Python</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <h1 id="面向对象Q-amp-A"><a href="#面向对象Q-amp-A" class="headerlink" title="面向对象Q&amp;A"></a>面向对象Q&amp;A</h1><h4 id="1-问-为什么类的私有属性-例如-name-从外部不能直接访问"><a href="#1-问-为什么类的私有属性-例如-name-从外部不能直接访问" class="headerlink" title="1. 问: 为什么类的私有属性(例如:__name),从外部不能直接访问?"></a>1. 问: 为什么类的私有属性(例如:__name),从外部不能直接访问?</h4><h5 id="答-因为实例化以后会改变私有属性的名称-变成-“-类名-私有属性”-所以不能用原来的私有属性直接访问-另外也并不建议使用”-类名-私有属性”去强行访问-因为不同版本的解释器有可能会把私有属性改成不同的属性名"><a href="#答-因为实例化以后会改变私有属性的名称-变成-“-类名-私有属性”-所以不能用原来的私有属性直接访问-另外也并不建议使用”-类名-私有属性”去强行访问-因为不同版本的解释器有可能会把私有属性改成不同的属性名" class="headerlink" title="答: 因为实例化以后会改变私有属性的名称, 变成 “__类名__私有属性”, 所以不能用原来的私有属性直接访问;另外也并不建议使用”__类名__私有属性”去强行访问,因为不同版本的解释器有可能会把私有属性改成不同的属性名!"></a>答: 因为实例化以后会改变私有属性的名称, 变成 “__类名__私有属性”, 所以不能用原来的私有属性直接访问;另外也并不建议使用”__类名__私有属性”去强行访问,因为不同版本的解释器有可能会把私有属性改成不同的属性名!</h5><a id="more"></a>

<h4 id="2-问-一个类中的单下划线属性-例如-age-是私有属性吗"><a href="#2-问-一个类中的单下划线属性-例如-age-是私有属性吗" class="headerlink" title="2. 问: 一个类中的单下划线属性(例如: _age)是私有属性吗?"></a>2. 问: 一个类中的单下划线属性(例如: _age)是私有属性吗?</h4><h5 id="答-其实单下划线开头的属性并不是私有属性-但是约定俗称的视为私有-所以即使可以从外部直接访问-但是不建议"><a href="#答-其实单下划线开头的属性并不是私有属性-但是约定俗称的视为私有-所以即使可以从外部直接访问-但是不建议" class="headerlink" title="答: 其实单下划线开头的属性并不是私有属性,但是约定俗称的视为私有, 所以即使可以从外部直接访问,但是不建议"></a>答: 其实单下划线开头的属性并不是私有属性,但是约定俗称的视为私有, 所以即使可以从外部直接访问,但是不建议</h5><h4 id="3-问-类里面前后都有双下划线的属性-例如-name-是啥-能直接访问吗"><a href="#3-问-类里面前后都有双下划线的属性-例如-name-是啥-能直接访问吗" class="headerlink" title="3. 问: 类里面前后都有双下划线的属性(例如:__name__)是啥,能直接访问吗?"></a>3. 问: 类里面前后都有双下划线的属性(例如:__name__)是啥,能直接访问吗?</h4><h5 id="答-是特殊属性-可以直接从外部访问-但是因为本身有特殊用途的属性才这样命名-所以一般我们定义的属性不能使用这种方式命名"><a href="#答-是特殊属性-可以直接从外部访问-但是因为本身有特殊用途的属性才这样命名-所以一般我们定义的属性不能使用这种方式命名" class="headerlink" title="答: 是特殊属性, 可以直接从外部访问, 但是因为本身有特殊用途的属性才这样命名,所以一般我们定义的属性不能使用这种方式命名!"></a>答: 是特殊属性, 可以直接从外部访问, 但是因为本身有特殊用途的属性才这样命名,所以一般我们定义的属性不能使用这种方式命名!</h5><h4 id="4-问-私有属性不能从外部访问-那如果就想访问怎么办呢"><a href="#4-问-私有属性不能从外部访问-那如果就想访问怎么办呢" class="headerlink" title="4. 问: 私有属性不能从外部访问, 那如果就想访问怎么办呢?"></a>4. 问: 私有属性不能从外部访问, 那如果就想访问怎么办呢?</h4><h5 id="答-可以定义获取私有属性的方法-把私有属性给return出来"><a href="#答-可以定义获取私有属性的方法-把私有属性给return出来" class="headerlink" title="答: 可以定义获取私有属性的方法, 把私有属性给return出来"></a>答: 可以定义获取私有属性的方法, 把私有属性给return出来</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Student</span><span class="params">(object)</span>:</span></span><br><span class="line">	<span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, name)</span>:</span></span><br><span class="line">        self.__name = name</span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">get_name</span><span class="params">(self)</span>:</span></span><br><span class="line">        <span class="keyword">return</span> self.__name</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">stu = Student(<span class="string">"laowang"</span>)</span><br><span class="line">stu.get_name()  <span class="comment"># 调用方法获取私有属性</span></span><br></pre></td></tr></table></figure>

<h4 id="5-问-不仅想从外部访问私有属性-还想修改私有属性-怎么办"><a href="#5-问-不仅想从外部访问私有属性-还想修改私有属性-怎么办" class="headerlink" title="5. 问: 不仅想从外部访问私有属性, 还想修改私有属性,怎么办?"></a>5. 问: 不仅想从外部访问私有属性, 还想修改私有属性,怎么办?</h4><h5 id="答-还是可以定义一个修改私有属性的方法-通过调用方法去修改私有属性的值"><a href="#答-还是可以定义一个修改私有属性的方法-通过调用方法去修改私有属性的值" class="headerlink" title="答: 还是可以定义一个修改私有属性的方法,通过调用方法去修改私有属性的值"></a>答: 还是可以定义一个修改私有属性的方法,通过调用方法去修改私有属性的值</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">set_name</span><span class="params">(self, name)</span>:</span></span><br><span class="line">        self.__name = name</span><br><span class="line">        </span><br><span class="line">stu.set_name(<span class="string">"xiaowang"</span>)</span><br></pre></td></tr></table></figure>

<h4 id="6-问-如果从外部动态的修改私有属性-能修改成功吗"><a href="#6-问-如果从外部动态的修改私有属性-能修改成功吗" class="headerlink" title="6. 问 : 如果从外部动态的修改私有属性,能修改成功吗?"></a>6. 问 : 如果从外部动态的修改私有属性,能修改成功吗?</h4><h5 id="答-首先从外部动态绑定的属性-即使前缀是双下划线-甚至和原来的私有属性同名-它都不会是一个私有属性-而是一个新的普通实例属性-可以从外部直接访问-而且私有属性在实例化以后其实已经不再是原来的名字了-新的名字不容易推断-会根据解释器不同而改变-所以仅和类中定义的私有属性同名是无法修改私有属性的"><a href="#答-首先从外部动态绑定的属性-即使前缀是双下划线-甚至和原来的私有属性同名-它都不会是一个私有属性-而是一个新的普通实例属性-可以从外部直接访问-而且私有属性在实例化以后其实已经不再是原来的名字了-新的名字不容易推断-会根据解释器不同而改变-所以仅和类中定义的私有属性同名是无法修改私有属性的" class="headerlink" title="答: 首先从外部动态绑定的属性, 即使前缀是双下划线, 甚至和原来的私有属性同名, 它都不会是一个私有属性, 而是一个新的普通实例属性, 可以从外部直接访问;而且私有属性在实例化以后其实已经不再是原来的名字了(新的名字不容易推断,会根据解释器不同而改变), 所以仅和类中定义的私有属性同名是无法修改私有属性的"></a>答: 首先从外部动态绑定的属性, 即使前缀是双下划线, 甚至和原来的私有属性同名, 它都不会是一个私有属性, 而是一个新的普通实例属性, 可以从外部直接访问;而且私有属性在实例化以后其实已经不再是原来的名字了(新的名字不容易推断,会根据解释器不同而改变), 所以仅和类中定义的私有属性同名是无法修改私有属性的</h5><h4 id="7-问-私有属性干什么用的"><a href="#7-问-私有属性干什么用的" class="headerlink" title="7. 问: 私有属性干什么用的?"></a>7. 问: 私有属性干什么用的?</h4><h5 id="答-限制访问用的-当你不想让外部代码随意改变对象的内部状态时-就可以使用私有属性-私有变量-把内部变量保护起来"><a href="#答-限制访问用的-当你不想让外部代码随意改变对象的内部状态时-就可以使用私有属性-私有变量-把内部变量保护起来" class="headerlink" title="答: 限制访问用的, 当你不想让外部代码随意改变对象的内部状态时, 就可以使用私有属性(私有变量)把内部变量保护起来"></a>答: 限制访问用的, 当你不想让外部代码随意改变对象的内部状态时, 就可以使用私有属性(私有变量)把内部变量保护起来</h5><h4 id="8-问-啥是基类-啥是父类-啥又是超类"><a href="#8-问-啥是基类-啥是父类-啥又是超类" class="headerlink" title="8. 问: 啥是基类?啥是父类?啥又是超类?"></a>8. 问: 啥是基类?啥是父类?啥又是超类?</h4><h5 id="答-基类-父类-超类-本身就是同一个概念-都是指面向对象继承中被继承的一方"><a href="#答-基类-父类-超类-本身就是同一个概念-都是指面向对象继承中被继承的一方" class="headerlink" title="答: 基类 父类 超类 本身就是同一个概念, 都是指面向对象继承中被继承的一方!"></a>答: 基类 父类 超类 本身就是同一个概念, 都是指面向对象继承中被继承的一方!</h5><h4 id="9-问-多态是啥东西"><a href="#9-问-多态是啥东西" class="headerlink" title="9: 问: 多态是啥东西?"></a>9: 问: 多态是啥东西?</h4><h5 id="答-我们在定义类class时-其实就是定义了一个数据类型-那么实例后的对象自然就属于这个类型-又因为有继承的存在-那么实例对象既是当前类的数据类型-又是父类的数据类型-反之则不行"><a href="#答-我们在定义类class时-其实就是定义了一个数据类型-那么实例后的对象自然就属于这个类型-又因为有继承的存在-那么实例对象既是当前类的数据类型-又是父类的数据类型-反之则不行" class="headerlink" title="答: 我们在定义类class时, 其实就是定义了一个数据类型, 那么实例后的对象自然就属于这个类型; 又因为有继承的存在, 那么实例对象既是当前类的数据类型,又是父类的数据类型, 反之则不行!"></a>答: 我们在定义类class时, 其实就是定义了一个数据类型, 那么实例后的对象自然就属于这个类型; 又因为有继承的存在, 那么实例对象既是当前类的数据类型,又是父类的数据类型, 反之则不行!</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Animal</span><span class="params">(object)</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">is_animal</span><span class="params">(self)</span>:</span></span><br><span class="line">        print(<span class="string">"is animal"</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Dog</span><span class="params">(Animal)</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">is_dog</span><span class="params">(self)</span>:</span></span><br><span class="line">        print(<span class="string">"is dog"</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">xb = Dog()</span><br><span class="line">print(isinstance(xb, Dog))  <span class="comment"># True</span></span><br><span class="line">print(isinstance(xb, Animal))  <span class="comment"># True 是狗一定是动物</span></span><br><span class="line"></span><br><span class="line">dh = Animal()</span><br><span class="line">print(isinstance(dh, Animal))  <span class="comment"># True</span></span><br><span class="line">print(isinstance(dh, Dog))  <span class="comment"># False 是动物但不一定是狗</span></span><br></pre></td></tr></table></figure>

<h4 id="10-问-多态有啥好处"><a href="#10-问-多态有啥好处" class="headerlink" title="10. 问: 多态有啥好处?"></a>10. 问: 多态有啥好处?</h4><h5 id="答-继承自统一个父类的所有子类-如果都有一个同名方法-那么如果公共方法正好调用对象的这个同名方法时-在传入不同实例的情况下会自动调用对应的方法-而不用修改公共方法本身"><a href="#答-继承自统一个父类的所有子类-如果都有一个同名方法-那么如果公共方法正好调用对象的这个同名方法时-在传入不同实例的情况下会自动调用对应的方法-而不用修改公共方法本身" class="headerlink" title="答: 继承自统一个父类的所有子类, 如果都有一个同名方法, 那么如果公共方法正好调用对象的这个同名方法时, 在传入不同实例的情况下会自动调用对应的方法, 而不用修改公共方法本身!"></a>答: 继承自统一个父类的所有子类, 如果都有一个同名方法, 那么如果公共方法正好调用对象的这个同名方法时, 在传入不同实例的情况下会自动调用对应的方法, 而不用修改公共方法本身!</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">run_once</span><span class="params">(animal)</span>:</span></span><br><span class="line">    animal.run()</span><br><span class="line">    </span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Animal</span><span class="params">(object)</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">run</span><span class="params">(self)</span>:</span></span><br><span class="line">        print(<span class="string">"Animal is running..."</span>)</span><br><span class="line">        </span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Dog</span><span class="params">(Animal)</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">run</span><span class="params">(self)</span>:</span></span><br><span class="line">        print(<span class="string">"Dog is running..."</span>)</span><br><span class="line">        </span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Cat</span><span class="params">(Animal)</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">run</span><span class="params">(self)</span>:</span></span><br><span class="line">        print(<span class="string">"Cat is running..."</span>)</span><br><span class="line"></span><br><span class="line">     </span><br><span class="line">run_once(Animal())  <span class="comment"># "Animal is running..."</span></span><br><span class="line">run_once(Dog())  <span class="comment"># "Dog is running..."</span></span><br><span class="line">run_once(Cat())  <span class="comment"># "Cat is running..."</span></span><br></pre></td></tr></table></figure>

<h4 id="11-问-啥是鸭子类型"><a href="#11-问-啥是鸭子类型" class="headerlink" title="11. 问: 啥是鸭子类型?"></a>11. 问: 啥是鸭子类型?</h4><h5 id="答-对于静态语言（例如Java）来说，如果需要传入Animal类型，则传入的对象必须是Animal类型或者它的子类，否则，将无法调用run-方法。对于Python这样的动态语言来说，则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run-方法就可以了-这就是动态语言的“鸭子类型”，它并不要求严格的继承体系"><a href="#答-对于静态语言（例如Java）来说，如果需要传入Animal类型，则传入的对象必须是Animal类型或者它的子类，否则，将无法调用run-方法。对于Python这样的动态语言来说，则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run-方法就可以了-这就是动态语言的“鸭子类型”，它并不要求严格的继承体系" class="headerlink" title="答:  对于静态语言（例如Java）来说，如果需要传入Animal类型，则传入的对象必须是Animal类型或者它的子类，否则，将无法调用run()方法。对于Python这样的动态语言来说，则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了;这就是动态语言的“鸭子类型”，它并不要求严格的继承体系"></a>答:  对于静态语言（例如Java）来说，如果需要传入<code>Animal</code>类型，则传入的对象必须是<code>Animal</code>类型或者它的子类，否则，将无法调用<code>run()</code>方法。对于Python这样的动态语言来说，则不一定需要传入<code>Animal</code>类型。我们只需要保证传入的对象有一个<code>run()</code>方法就可以了;这就是动态语言的“鸭子类型”，它并不要求严格的继承体系</h5> <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Duck</span><span class="params">(object)</span>:</span>  <span class="comment"># Duck继承自object类,并没继承自Animal类</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">run</span><span class="params">(self)</span>:</span></span><br><span class="line">        print(<span class="string">"Duck is running..."</span>)</span><br><span class="line">        </span><br><span class="line"></span><br><span class="line">run_once(Duck())  <span class="comment"># "Duck is running..."  既使不继承自Animal依然可以调用</span></span><br></pre></td></tr></table></figure>

<h4 id="12-问-可以给类动态地绑定方法吗"><a href="#12-问-可以给类动态地绑定方法吗" class="headerlink" title="12. 问: 可以给类动态地绑定方法吗?"></a>12. 问: 可以给类动态地绑定方法吗?</h4><h5 id="答-可以-直接在外部使用-“类名-方法名-方法”即可"><a href="#答-可以-直接在外部使用-“类名-方法名-方法”即可" class="headerlink" title="答: 可以, 直接在外部使用 “类名.方法名 = 方法”即可"></a>答: 可以, 直接在外部使用 “类名.方法名 = 方法”即可</h5><h4 id="13-问-想要限制从外部添加的实例属性-怎么做"><a href="#13-问-想要限制从外部添加的实例属性-怎么做" class="headerlink" title="13. 问: 想要限制从外部添加的实例属性, 怎么做?"></a>13. 问: 想要限制从外部添加的实例属性, 怎么做?</h4><h5 id="答-在类的内部-使用特殊变量-slots-“-“-“-“-…-去限定能够添加的属性名-试图从外部添加限定外的属性时-会报错"><a href="#答-在类的内部-使用特殊变量-slots-“-“-“-“-…-去限定能够添加的属性名-试图从外部添加限定外的属性时-会报错" class="headerlink" title="答:在类的内部, 使用特殊变量__slots__=(“ “, “  “, …)去限定能够添加的属性名, 试图从外部添加限定外的属性时, 会报错"></a>答:在类的内部, 使用特殊变量__slots__=(“ “, “  “, …)去限定能够添加的属性名, 试图从外部添加限定外的属性时, 会报错</h5><h4 id="14-问-slots-定义的限制属性对子类实例起作用吗"><a href="#14-问-slots-定义的限制属性对子类实例起作用吗" class="headerlink" title="14. 问: __slots__定义的限制属性对子类实例起作用吗?"></a>14. 问: __slots__定义的限制属性对子类实例起作用吗?</h4><h5 id="答-slots-定义的属性仅对当前类实例起作用，对继承的子类是不起作用的"><a href="#答-slots-定义的属性仅对当前类实例起作用，对继承的子类是不起作用的" class="headerlink" title="答: __slots__定义的属性仅对当前类实例起作用，对继承的子类是不起作用的;"></a>答: __slots__定义的属性仅对当前类实例起作用，对继承的子类是不起作用的;</h5><h4 id="15-问-如果父类定义了-slots-子类中又定义了-slots-会怎么样"><a href="#15-问-如果父类定义了-slots-子类中又定义了-slots-会怎么样" class="headerlink" title="15. 问: 如果父类定义了 __slots__, 子类中又定义了 __slots__会怎么样?"></a>15. 问: 如果父类定义了 __slots__, 子类中又定义了 __slots__会怎么样?</h4><h5 id="答-此时-子类实例限制添加的属性就等于”父类限制-子类限制”-也就是如果子类也定义-slots-则自动继承父类的-slots"><a href="#答-此时-子类实例限制添加的属性就等于”父类限制-子类限制”-也就是如果子类也定义-slots-则自动继承父类的-slots" class="headerlink" title="答: 此时, 子类实例限制添加的属性就等于”父类限制+子类限制”, 也就是如果子类也定义 __slots__则自动继承父类的 __slots__"></a>答: 此时, 子类实例限制添加的属性就等于”父类限制+子类限制”, 也就是如果子类也定义 __slots__则自动继承父类的 __slots__</h5><h4 id="16-问-为什么需要-property装饰器呢"><a href="#16-问-为什么需要-property装饰器呢" class="headerlink" title="16. 问: 为什么需要@property装饰器呢?"></a>16. 问: 为什么需要@property装饰器呢?</h4><h5 id="答-直接使用外部添加、修改、访问的方式去操作属性-太暴露且不能定义参数检验-容易导致属性被胡乱修改-而在类的内部对一个属性定义多个操作函数又略显杂乱-所以此时就需要-property装饰器把函数当属性用"><a href="#答-直接使用外部添加、修改、访问的方式去操作属性-太暴露且不能定义参数检验-容易导致属性被胡乱修改-而在类的内部对一个属性定义多个操作函数又略显杂乱-所以此时就需要-property装饰器把函数当属性用" class="headerlink" title="答: 直接使用外部添加、修改、访问的方式去操作属性, 太暴露且不能定义参数检验, 容易导致属性被胡乱修改; 而在类的内部对一个属性定义多个操作函数又略显杂乱, 所以此时就需要@property装饰器把函数当属性用"></a>答: 直接使用外部添加、修改、访问的方式去操作属性, 太暴露且不能定义参数检验, 容易导致属性被胡乱修改; 而在类的内部对一个属性定义多个操作函数又略显杂乱, 所以此时就需要@property装饰器把函数当属性用</h5><h4 id="17-问-property装饰器的好处是啥"><a href="#17-问-property装饰器的好处是啥" class="headerlink" title="17. 问 : @property装饰器的好处是啥?"></a>17. 问 : @property装饰器的好处是啥?</h4><h5 id="答-可以让调用者写出简短的代码，同时保证对参数进行必要的检查，这样，程序运行时就减少了出错的可能性"><a href="#答-可以让调用者写出简短的代码，同时保证对参数进行必要的检查，这样，程序运行时就减少了出错的可能性" class="headerlink" title="答: 可以让调用者写出简短的代码，同时保证对参数进行必要的检查，这样，程序运行时就减少了出错的可能性"></a>答: 可以让调用者写出简短的代码，同时保证对参数进行必要的检查，这样，程序运行时就减少了出错的可能性</h5><h4 id="18-问-怎么使用-property装饰器呢"><a href="#18-问-怎么使用-property装饰器呢" class="headerlink" title="18. 问: 怎么使用@property装饰器呢?"></a>18. 问: 怎么使用@property装饰器呢?</h4><h5 id="答-首先在获取属性的方法加上-property装饰器-然后在设置-修改-属性的方法上面加上-属性名-setter的装饰器-如果是只读属性就在读方法上面加一个-property装饰器即可"><a href="#答-首先在获取属性的方法加上-property装饰器-然后在设置-修改-属性的方法上面加上-属性名-setter的装饰器-如果是只读属性就在读方法上面加一个-property装饰器即可" class="headerlink" title="答: 首先在获取属性的方法加上@property装饰器, 然后在设置(修改)属性的方法上面加上@属性名.setter的装饰器, 如果是只读属性就在读方法上面加一个@property装饰器即可"></a>答: 首先在获取属性的方法加上@property装饰器, 然后在设置(修改)属性的方法上面加上@属性名.setter的装饰器, 如果是只读属性就在读方法上面加一个@property装饰器即可</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Student</span><span class="params">(object)</span>:</span></span><br><span class="line"></span><br><span class="line"><span class="meta">    @property</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">birth</span><span class="params">(self)</span>:</span>  <span class="comment"># birth的读方法</span></span><br><span class="line">        <span class="keyword">return</span> self._birth</span><br><span class="line"></span><br><span class="line"><span class="meta">    @birth.setter</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">birth</span><span class="params">(self, value)</span>:</span>  <span class="comment"># birth的写方法</span></span><br><span class="line">        self._birth = value</span><br><span class="line"></span><br><span class="line"><span class="meta">    @property</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">age</span><span class="params">(self)</span>:</span>  <span class="comment"># 只读属性</span></span><br><span class="line">        <span class="keyword">return</span> <span class="number">2015</span> - self._birth</span><br></pre></td></tr></table></figure>

<h4 id="19-问-怎么理解Mixin"><a href="#19-问-怎么理解Mixin" class="headerlink" title="19. 问: 怎么理解Mixin?"></a>19. 问: 怎么理解Mixin?</h4><h5 id="答-多继承中-非主线继承的类-为了增加混入的其他功能的类在命名时一般会加上Mixin以作区别-通过直接继承Mixin类-可以避免设计过于复杂的继承路线-使类的层级结构更清晰"><a href="#答-多继承中-非主线继承的类-为了增加混入的其他功能的类在命名时一般会加上Mixin以作区别-通过直接继承Mixin类-可以避免设计过于复杂的继承路线-使类的层级结构更清晰" class="headerlink" title="答: 多继承中,非主线继承的类, 为了增加混入的其他功能的类在命名时一般会加上Mixin以作区别;通过直接继承Mixin类,可以避免设计过于复杂的继承路线, 使类的层级结构更清晰"></a>答: 多继承中,非主线继承的类, 为了增加混入的其他功能的类在命名时一般会加上Mixin以作区别;通过直接继承Mixin类,可以避免设计过于复杂的继承路线, 使类的层级结构更清晰</h5><h4 id="20-问-str-和-repr-分别是干嘛用的"><a href="#20-问-str-和-repr-分别是干嘛用的" class="headerlink" title="20. 问: __str__和__repr__分别是干嘛用的?"></a>20. 问: __str__和__repr__分别是干嘛用的?</h4><h5 id="答-都是可以自定义输出格式的方法-str-主要面向用户-而-repr-主要是给程序员看的-使用print-方法打印对象-才会调用-str-如果直接显示变量-例如在控制台-则会调用-repr-偷懒的定义方法-只定义一个-str-然后-repr-str-即可统一输出格式"><a href="#答-都是可以自定义输出格式的方法-str-主要面向用户-而-repr-主要是给程序员看的-使用print-方法打印对象-才会调用-str-如果直接显示变量-例如在控制台-则会调用-repr-偷懒的定义方法-只定义一个-str-然后-repr-str-即可统一输出格式" class="headerlink" title="答: 都是可以自定义输出格式的方法; __str__主要面向用户, 而 __repr__主要是给程序员看的, 使用print()方法打印对象, 才会调用 __str__, 如果直接显示变量(例如在控制台)则会调用 __repr__; 偷懒的定义方法, 只定义一个__str__,然后 __repr__ = __str__即可统一输出格式"></a>答: 都是可以自定义输出格式的方法; __str__主要面向用户, 而 __repr__主要是给程序员看的, 使用print()方法打印对象, 才会调用 __str__, 如果直接显示变量(例如在控制台)则会调用 __repr__; 偷懒的定义方法, 只定义一个__str__,然后 __repr__ = __str__即可统一输出格式</h5><h4 id="21-问-iter-干嘛用的-next-又是干嘛用的"><a href="#21-问-iter-干嘛用的-next-又是干嘛用的" class="headerlink" title="21. 问: __iter__()干嘛用的?__next__()又是干嘛用的?"></a>21. 问: __iter__()干嘛用的?__next__()又是干嘛用的?</h4><h5 id="答-如果一个类想要用于for-in-循环-则必须实现一个-iter-方法-返回一个可迭代对象-也就是实例本身self-for循环就会不断地调用实例的-next-方法拿到循环的下一个值-直到StopIteration"><a href="#答-如果一个类想要用于for-in-循环-则必须实现一个-iter-方法-返回一个可迭代对象-也就是实例本身self-for循环就会不断地调用实例的-next-方法拿到循环的下一个值-直到StopIteration" class="headerlink" title="答: 如果一个类想要用于for in 循环, 则必须实现一个__iter__()方法, 返回一个可迭代对象, 也就是实例本身self ; for循环就会不断地调用实例的__next__()方法拿到循环的下一个值, 直到StopIteration"></a>答: 如果一个类想要用于for in 循环, 则必须实现一个__iter__()方法, 返回一个可迭代对象, 也就是实例本身self ; for循环就会不断地调用实例的__next__()方法拿到循环的下一个值, 直到StopIteration</h5><h4 id="22-问-一个可迭代的实例对象-想要使用下标和切片访问-怎么实现"><a href="#22-问-一个可迭代的实例对象-想要使用下标和切片访问-怎么实现" class="headerlink" title="22. 问: 一个可迭代的实例对象, 想要使用下标和切片访问, 怎么实现?"></a>22. 问: 一个可迭代的实例对象, 想要使用下标和切片访问, 怎么实现?</h4><h5 id="答-使用-getitem-方法实现-注意需要判断传入的参数是int还是slice类型-以区别下标访问和切片访问-但是这里的切片不能对step参数处理-也就是不能自定义步长-同时也不能使用复数"><a href="#答-使用-getitem-方法实现-注意需要判断传入的参数是int还是slice类型-以区别下标访问和切片访问-但是这里的切片不能对step参数处理-也就是不能自定义步长-同时也不能使用复数" class="headerlink" title="答: 使用__getitem__()方法实现, 注意需要判断传入的参数是int还是slice类型, 以区别下标访问和切片访问; 但是这里的切片不能对step参数处理, 也就是不能自定义步长, 同时也不能使用复数"></a>答: 使用__getitem__()方法实现, 注意需要判断传入的参数是int还是slice类型, 以区别下标访问和切片访问; 但是这里的切片不能对step参数处理, 也就是不能自定义步长, 同时也不能使用复数</h5><h4 id="23-问-除了-getitem-以外-setitem-和-delitem-又是干嘛用的"><a href="#23-问-除了-getitem-以外-setitem-和-delitem-又是干嘛用的" class="headerlink" title="23. 问: 除了__getitem__()以外, __setitem__()和__delitem__()又是干嘛用的?"></a>23. 问: 除了__getitem__()以外, __setitem__()和__delitem__()又是干嘛用的?</h4><h5 id="答-setitem-把实例对象视为list或dict来对集合赋值-delitem-用来删除某个元素-通过这3个方法-我们自己构造的类和python自带的list-tuple-dict-也差不多了-类似鸭子类型"><a href="#答-setitem-把实例对象视为list或dict来对集合赋值-delitem-用来删除某个元素-通过这3个方法-我们自己构造的类和python自带的list-tuple-dict-也差不多了-类似鸭子类型" class="headerlink" title="答:  __setitem__()把实例对象视为list或dict来对集合赋值, __delitem__()用来删除某个元素; 通过这3个方法, 我们自己构造的类和python自带的list, tuple, dict 也差不多了, 类似鸭子类型"></a>答:  __setitem__()把实例对象视为list或dict来对集合赋值, __delitem__()用来删除某个元素; 通过这3个方法, 我们自己构造的类和python自带的list, tuple, dict 也差不多了, 类似鸭子类型</h5><h4 id="24-问-getattr-self-attr-是用来做什么的"><a href="#24-问-getattr-self-attr-是用来做什么的" class="headerlink" title="24. 问: __getattr__(self, attr)是用来做什么的?"></a>24. 问: __getattr__(self, attr)是用来做什么的?</h4><h5 id="答-访问类中不存在的属性或者调用不存在的方法时-会调用-getattr-方法-可以自定义返回的值-默认返回None值-可以使用-raise-AttributeError-“-“-attr-去格式化想输出的错误信息"><a href="#答-访问类中不存在的属性或者调用不存在的方法时-会调用-getattr-方法-可以自定义返回的值-默认返回None值-可以使用-raise-AttributeError-“-“-attr-去格式化想输出的错误信息" class="headerlink" title="答: 访问类中不存在的属性或者调用不存在的方法时, 会调用 __getattr__方法, 可以自定义返回的值 ; 默认返回None值, 可以使用 raise AttributeError (“  “, attr)去格式化想输出的错误信息"></a>答: 访问类中不存在的属性或者调用不存在的方法时, 会调用 __getattr__方法, 可以自定义返回的值 ; 默认返回None值, 可以使用 raise AttributeError (“  “, attr)去格式化想输出的错误信息</h5><h4 id="25-问-当一个实例想要调用实例方法时-一般会以instance-method-这种方式调用-那可不可以直接使用instance-调用呢"><a href="#25-问-当一个实例想要调用实例方法时-一般会以instance-method-这种方式调用-那可不可以直接使用instance-调用呢" class="headerlink" title="25. 问: 当一个实例想要调用实例方法时, 一般会以instance.method()这种方式调用, 那可不可以直接使用instance()调用呢?"></a>25. 问: 当一个实例想要调用实例方法时, 一般会以instance.method()这种方式调用, 那可不可以直接使用instance()调用呢?</h4><h5 id="答-可以-定义一个-call-方法-相当于就把实例对象看成一个函数去调用"><a href="#答-可以-定义一个-call-方法-相当于就把实例对象看成一个函数去调用" class="headerlink" title="答: 可以, 定义一个__call__()方法, 相当于就把实例对象看成一个函数去调用"></a>答: 可以, 定义一个__call__()方法, 相当于就把实例对象看成一个函数去调用</h5><h4 id="26-问-那怎么判断一个对象能否被调用呢"><a href="#26-问-那怎么判断一个对象能否被调用呢" class="headerlink" title="26. 问: 那怎么判断一个对象能否被调用呢?"></a>26. 问: 那怎么判断一个对象能否被调用呢?</h4><h5 id="答-只需要判断一个对象是否可以被调用-使用callable-对象-函数判断是否是可调用callable的对象"><a href="#答-只需要判断一个对象是否可以被调用-使用callable-对象-函数判断是否是可调用callable的对象" class="headerlink" title="答: 只需要判断一个对象是否可以被调用, 使用callable(对象)函数判断是否是可调用callable的对象,"></a>答: 只需要判断一个对象是否可以被调用, 使用callable(对象)函数判断是否是可调用callable的对象,</h5><h4 id="27-问-需要定义常量时-怎么使用枚举类"><a href="#27-问-需要定义常量时-怎么使用枚举类" class="headerlink" title="27. 问: 需要定义常量时, 怎么使用枚举类?"></a>27. 问: 需要定义常量时, 怎么使用枚举类?</h4><h5 id="答-from-enum-import-Enum-导入枚举类-枚举类的value属性是自动赋值给成员的int型常量-注意是从1开始的-还可以导入-unique装饰器保证没有重复值"><a href="#答-from-enum-import-Enum-导入枚举类-枚举类的value属性是自动赋值给成员的int型常量-注意是从1开始的-还可以导入-unique装饰器保证没有重复值" class="headerlink" title="答: from enum import Enum 导入枚举类, 枚举类的value属性是自动赋值给成员的int型常量, 注意是从1开始的   ; 还可以导入@unique装饰器保证没有重复值"></a>答: from enum import Enum 导入枚举类, 枚举类的value属性是自动赋值给成员的int型常量, 注意是从1开始的   ; 还可以导入@unique装饰器保证没有重复值</h5><h4 id="28-问-不使用class还能怎么样创建一个类呢"><a href="#28-问-不使用class还能怎么样创建一个类呢" class="headerlink" title="28. 问: 不使用class还能怎么样创建一个类呢?"></a>28. 问: 不使用class还能怎么样创建一个类呢?</h4><h5 id="答-使用type-既可以查看对象的类型-同时又可用于创建类-事实上解释器在扫描完class定义的语法后就是使用type去创建这个类的-使用type-相当于是动态的创建类-type-类名-继承的父类-…-dict-类的方法名-外部方法"><a href="#答-使用type-既可以查看对象的类型-同时又可用于创建类-事实上解释器在扫描完class定义的语法后就是使用type去创建这个类的-使用type-相当于是动态的创建类-type-类名-继承的父类-…-dict-类的方法名-外部方法" class="headerlink" title="答: 使用type()既可以查看对象的类型, 同时又可用于创建类 ; 事实上解释器在扫描完class定义的语法后就是使用type去创建这个类的; 使用type()相当于是动态的创建类, type(类名, (继承的父类, …), dict(类的方法名=外部方法))"></a>答: 使用type()既可以查看对象的类型, 同时又可用于创建类 ; 事实上解释器在扫描完class定义的语法后就是使用type去创建这个类的; 使用type()相当于是动态的创建类, type(类名, (继承的父类, …), dict(类的方法名=外部方法))</h5><h4 id="29-问-什么是元类metaclass"><a href="#29-问-什么是元类metaclass" class="headerlink" title="29. 问: 什么是元类metaclass?"></a>29. 问: 什么是元类metaclass?</h4><h5 id="答-元类允许创建或修改类-metaclass-gt-class-gt-instance-元类用来控制类的创建行为-定义元类一般以Metaclass结尾-是Python面向对象里最难理解，也是最难使用的魔术代码"><a href="#答-元类允许创建或修改类-metaclass-gt-class-gt-instance-元类用来控制类的创建行为-定义元类一般以Metaclass结尾-是Python面向对象里最难理解，也是最难使用的魔术代码" class="headerlink" title="答:  元类允许创建或修改类 metaclass==&gt;class==&gt;instance, 元类用来控制类的创建行为, 定义元类一般以Metaclass结尾, 是Python面向对象里最难理解，也是最难使用的魔术代码"></a>答:  元类允许创建或修改类 metaclass==&gt;class==&gt;instance, 元类用来控制类的创建行为, 定义元类一般以Metaclass结尾, 是Python面向对象里最难理解，也是最难使用的魔术代码</h5>
    </div>

    
    
    

      <footer class="post-footer">
          <div class="post-tags">
              <a href="/blog/tags/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/" rel="tag"><i class="fa fa-tag"></i> 面向对象</a>
          </div>

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/blog/2020/07/02/Python%E5%8D%95%E9%93%BE%E8%A1%A8/" rel="prev" title="Python单链表">
      <i class="fa fa-chevron-left"></i> Python单链表
    </a></div>
      <div class="post-nav-item">
    <a href="/blog/2020/07/09/%E5%BC%80%E5%8F%91%E5%B8%B8%E7%94%A8Linux%E6%8C%87%E4%BB%A4/" rel="next" title="开发常用Linux指令">
      开发常用Linux指令 <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  



        </div>
        

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fas fa-yin-yang"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">张雪峰</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/muse/" class="theme-link" rel="noopener" target="_blank">NexT.Muse</a> 强力驱动
  </div>

        








      </div>
    </footer>
  </div>

  
  <script src="/blog/lib/anime.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/@fancyapps/fancybox@3/dist/jquery.fancybox.min.js"></script>
  <script src="/blog/lib/velocity/velocity.min.js"></script>
  <script src="/blog/lib/velocity/velocity.ui.min.js"></script>

<script src="/blog/js/utils.js"></script>

<script src="/blog/js/motion.js"></script>


<script src="/blog/js/schemes/muse.js"></script>


<script src="/blog/js/next-boot.js"></script>


  















  

  

</body>
</html>
